package com.netmi.myuploadfileretrofit;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.webkit.DownloadListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.netmi.myuploadfileretrofit.http.RxSchedulers;
import com.netmi.myuploadfileretrofit.inteface.RetrofitDownloadFile;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class DownloadVideoActivity extends AppCompatActivity {
    private static final String DEFAULT_MEDIA_URI =
            "https://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv";

    private static final String TAG = "tgwdown" + DownloadVideoActivity.class.getSimpleName();
    private Button btDownLoadVideo;
    private TextView tvAddress;


    String videoUrl = null;


    //设置EXOplayer播放参数
    //1.默认的播放View
    private PlayerView playerView;
    //    private PlayerControlView playerControlView;//另一个播放界面
    //2.您可以ExoPlayer使用创建实例ExoPlayerFactory。工厂提供了一系列方法来创建ExoPlayer具有不同
    //级别自定义的实例。对于绝大多数用例，ExoPlayerFactory.newSimpleInstance应该使用其中一种 方法。
    //这些方法返回SimpleExoPlayer
    private SimpleExoPlayer player = null;
    // Produces DataSource instances through which media data is loaded.--生成加载媒体数据的数据源实例。
    private DataSource.Factory dataSourceFactory = null;
    // This is the MediaSource representing the media to be played.---这是表示要播放的媒体的媒体源
    private MediaSource videoSource = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//（必须在setContentView 之前有效）
        setContentView(R.layout.activity_download_video);

        videoUrl = getIntent().getStringExtra("videoPath");
//        videoUrl=DEFAULT_MEDIA_URI;

        btDownLoadVideo = findViewById(R.id.bt_download_video);
        tvAddress = findViewById(R.id.tv_video_address);
        tvAddress.setText("网络视频地址：" + videoUrl);


        btDownLoadVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!TextUtils.isEmpty(videoUrl)) {
                    downLoadVideo(videoUrl);
                } else {
                    Toast.makeText(DownloadVideoActivity.this, "选择视频后才能播放", Toast.LENGTH_SHORT).show();
                }
            }
        });


    }

    private String getVideoOutCompressPath(Activity context) {
        String path = null;
        File file = null;
        long tag = System.currentTimeMillis();
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {//SDCard是否可用
            //最好把images替换成你的项目名称，避免有重复文件夹
            path = context.getExternalFilesDir(Environment.DIRECTORY_MOVIES) + File.separator + "videoCompress/";
            file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            Log.d(TAG, "compressVideo getVideoOutCompressPath--- getExternalFilesDir(Environment.DIRECTORY_MOVIES): " + context.getExternalFilesDir(Environment.DIRECTORY_MOVIES).getAbsolutePath());
            path = context.getExternalFilesDir(Environment.DIRECTORY_MOVIES) + File.separator + "videoCompress/" + tag + ".mp4";
        } else {
            Log.d(TAG, " compressVideo getVideoOutCompressPath---getFilesDir: " + context.getFilesDir().getAbsolutePath());
            path = context.getFilesDir() + File.separator + "videoCompress/";
            file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            path = context.getFilesDir() + File.separator + "videoCompress/" + tag + ".mp4";
        }
        Log.d(TAG, "compressVideo getVideoOutCompressPath---最终路径: " + path);

        return path;

    }

    private void initRetrofit() {


        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(MainActivity.BASE_URL)
//                .client(getOkHttpClient()) //自定义okhttp
                .addConverterFactory(GsonConverterFactory.create()) //gson转换器
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        RetrofitDownloadFile retrofitUploadFile = retrofit.create(RetrofitDownloadFile.class);
        //使用rxjava的方式
        Observable<ResponseBody> observable = retrofitUploadFile.downloadFileUrl(videoUrl);
        observable.compose(RxSchedulers.compose())
                .subscribe(new Observer<ResponseBody>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(ResponseBody responseBody) {
                        Thread mThread = new Thread() {
                            @Override
                            public void run() {
                                super.run();
                                //保存到本地
                                writeFile2Disk(responseBody, new File(getVideoOutCompressPath(DownloadVideoActivity.this)), null);

                            }
                        };
                        mThread.start();
//                        new DownloadFile().execute(responseBody.byteStream());
                        Log.d(TAG, "onNext: 上传完成地址" + responseBody.byteStream().toString());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError: 失败" + e.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete: 下载完成地址");
                    }
                });


    }


    /**
     * @param 第一个参数 ：传入的参数类型
     * @param 第二个参数 ：onProgressUpdate 中的参数
     * @param 第三个参数 ：doInBackground  中的返回类型
     */
    class DownloadFile extends AsyncTask<String, Integer, String> {

        //        该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作，比如加载几张默认的预览图
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        //         将在onPreExecute 方法执行后马上执行，该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。比如从网络拉取预览图， 每拉取一张以后， 可以调用 publishProgress方法来更新一张默认的图片。
        @Override
        protected String doInBackground(String... params) {
            if (params != null && params.length > 0) {
                String pdfUrl = params[0];

                try {
                    URL url = new URL(pdfUrl);
                    URLConnection urlConnection = url.openConnection();
                    InputStream in = urlConnection.getInputStream();
                    int contentLength = urlConnection.getContentLength();//获取内容总长度

                    String mFilePath = getVideoOutCompressPath(DownloadVideoActivity.this);

                    //若存在同名文件则删除
                    File pdfFile = new File(mFilePath);
                    if (pdfFile.exists()) {
                        boolean result = pdfFile.delete();
                    }

                    int downloadSize = 0;//已经下载的大小
                    byte[] bytes = new byte[1024];
                    int length = 0;
                    OutputStream out = new FileOutputStream(mFilePath);
                    while ((length = in.read(bytes)) != -1) {
                        out.write(bytes, 0, length);
                        downloadSize += length;
                        publishProgress(downloadSize / contentLength * 100);
                    }

                    in.close();
                    out.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            return null;
        }
//   在publishProgress方法被调用后，这个方法将被UI线程调用， 用于更新进度等界面显示。在上面那个例子中， 调用这个函数更新一张图片
        @Override
        protected void onProgressUpdate(Integer... values) {
            Log.e(TAG, "当前进度onProgressUpdate: " + values);
        }

// 在doInBackground 执行完成后，onPostExecute 方法将被UI thread调用，后台的计算结果将通过该方法传递到UI thread.
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            Log.e(TAG, "下载完成: ");
        }
    }


    private void downLoadVideo(String videoUrl) {
//        initRetrofit();
        new DownloadFile().execute(videoUrl);
    }

    //将下载的文件写入本地存储
    private void writeFile2Disk(ResponseBody response, File file, DownloadListener downloadListener) {

        long currentLength = 0;
        OutputStream os = null;

        InputStream is = response.byteStream(); //获取下载输入流
        long totalLength = response.contentLength();

        try {
            os = new FileOutputStream(file); //输出流
            int len;
            byte[] buff = new byte[1024];
            while ((len = is.read(buff)) != -1) {
                os.write(buff, 0, len);
                currentLength += len;
                Log.e(TAG, "当前进度: " + currentLength);
                //计算当前下载百分比，并经由回调传出
//                downloadListener.onProgress((int) (100 * currentLength / totalLength));
                //当百分比为100时下载结束，调用结束回调，并传出下载后的本地路径
                if ((int) (100 * currentLength / totalLength) == 100) {
//                    downloadListener.onFinish(mVideoPath); //下载完成
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                if (os != null) {
                    os.close(); //关闭输出流
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                if (is != null) {
                    is.close(); //关闭输入流
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
